package com.cloudy.security;

import static com.cloudy.impl.Constants.HOST_HEADER;

import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.cloudy.impl.AWSRequest;
import com.cloudy.impl.AwsURLEncoder;

public class EC2RequestSigner implements AWSRequestSigner{
	private static final String HTTP_VERB = "GET\n";
	private static final String HTTP_REQUEST_URI = "/\n";

	public void sign(AWSRequest request){
		String canonicalizedQueryString = getCanonicalizedQueryString(request);
		
		String stringToSign = new StringBuilder()	.append(HTTP_VERB)
													.append(HOST_HEADER+"\n")
													.append(HTTP_REQUEST_URI)
													.append(canonicalizedQueryString).toString();
		String signature = signTheString(stringToSign);
		request.putSignature(signature);
	}
	private String signTheString(String stringToSign) {
		String signature = null;
		try {
			signature = RFC2104HMAC.calculateRFC2104HMAC(stringToSign, AccessIdentifiers.getSecretAccessKey());
		} catch (SignatureException e) {
			throw new RuntimeException(e);
		}
		return signature;
	}
	private String getCanonicalizedQueryString(AWSRequest request) {
		List<String> componentz = getListOfEntries(request.getAttributes());
		Collections.sort(componentz);
		String canonicalizedQueryString = getCanonicalizedQueryString(componentz);
		return canonicalizedQueryString;
	}
	private void addComponentz(List<String> components,Map<String, String> attributes, String key) {
		components.add(AwsURLEncoder.urlEncode(key) + "=" + AwsURLEncoder.urlEncode(attributes.get(key)));
	}
	private List<String> getListOfEntries(Map<String, String> entries){
		List<String> components = new ArrayList<String>();
		for (Iterator<String> iterator = entries.keySet().iterator(); iterator.hasNext();) {
			String key = iterator.next();
			addComponentz(components, entries, key);
		}
		return components;
	}
	/**
	 * @param list
	 * @return
	 */
	private String getCanonicalizedQueryString(List<String> list){
		Iterator<String> it = list.iterator();
		StringBuilder result = new StringBuilder(it.next());
		while(it.hasNext()){
			result.append("&").append(it.next());
		}
		
		return result.toString();
	} 

}
